<?php

namespace App\Model\Common;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Redis;

class Common extends Model
{
    public $timestamps = false;
    public $error = '';

    protected $autoRefreshCache = false;
    protected $cacheKey = '';

    protected $unsetFields = ['id', 'create_time', 'update_time'];

    protected $parentKey = '';
    protected $parentCacheKey = '';

    public function __construct()
    {
        $class = get_class($this);
        $class = explode('\\', $class);
        $class = $class[count($class) - 1];
        $table = toUnderScore($class);
        $this->table = $table;
        // $this->getFillable();
        parent::__construct();
    }

    public function getError()
    {
        return $this->error;
    }

    public function fillData($data)
    {
        $this->getColumns();
        return $this->fill($data);
    }

    public function getColumns()
    {
        if (!empty($this->fillable)) {
            return $this->fillable;
        } else {
            $fields = Schema::getColumnListing($this->getTable());
            for ($i = 0; $i < count($fields); ++$i) {
                if (in_array($fields[$i], $this->unsetFields)) {
                    unset($fields[$i]);
                }
            }

            $this->fillable = $fields;

            return $this->fillable;
        }
    }

    // public function getFillable()
    // {
    //     if (!empty($this->fillable)) {
    //         return $this->fillable;
    //     } else {
    //         $fields = Schema::getColumnListing($this->getTable());
    //         for ($i = 0; $i < count($fields); ++$i) {
    //             if (in_array($fields[$i], $this->unsetFields)) {
    //                 unset($fields[$i]);
    //             }
    //         }

    //         $this->fillable = $fields;

    //         return $this->fillable;
    //     }
    // }

    public function refreshCache($obj, $mode)
    {
    }

    public function formatListDbData($data, $opt)
    {
        return $data;
    }

    public function formatOneDbData($data, $opt)
    {
        return $data;
    }

    public function getOne($id, $opt = [])
    {
        if (config('app.redis_on') && empty($opt['no_cache'])) {
            $data = Redis::hget($this->cacheKey, $id);
        }
        if (empty($data)) {
            $data = self::find($id);
            if (!$data) {
                return [];
            }
            $data = $this->formatOneDbData($data, $opt);
            if (config('app.redis_on')) {
                Redis::hset($this->cacheKey, $data->id, json_encode($data));
            }
        } else {
            $data = json_decode($data, true);
        }

        return $data;
    }

    public function getListByParentKey($id, $opt = [])
    {
        if (config('app.redis_on') && empty($opt['no_cache'])) {
            $data = Redis::hget($this->parentCacheKey, $id);
        }
        if (empty($data)) {
            $data = self::where($this->parentKey, $id)->get();
            if (!$data) {
                return [];
            }
            $data = $this->formatOneDbData($data, $opt);
            if (config('app.redis_on')) {
                Redis::hset($this->parentCacheKey, $id, json_encode($data));
            }
        } else {
            $data = json_decode($data, true);
        }

        return $data;
    }

    public function getList($ids = null, $opt = [])
    {
        if (config('app.redis_on') && empty($opt['no_cache'])) {
            if (empty($ids)) {
                $list = Redis::hgetall($this->cacheKey);
            } else {
                $list = Redis::hmget($this->cacheKey, $ids);
                foreach ($list as $k => $li) {
                    if (!$li) {
                        unset($list[$k]);
                    }
                }
            }
        }

        if (empty($list) || (!empty($opt['fill']) && count($ids) != count($list))) {
            $list = self::where(['status' => 1]);
            if (!empty($ids)) {
                $list = $list->where('id', 'in', $ids);
            }
            if (!empty($opt['order'])) {
                $list = $list->order($opt['order'])->select();
            } else {
                $list = $list->order('rank desc, id asc')->select();
            }
            $data = [];
            foreach ($list as $k => $li) {
                $data[$li['id']] = $li->getData();
            }

            $data = $this->formatListDbData($data, $opt);
            $list = $data;
            if (config('app.redis_on')) {
                foreach ($data as $id => $da) {
                    $data[$id] = json_encode($da);
                }
                redis()->hmset($this->cacheKey, $data);
            }
        } else {
            foreach ($list as $k => $li) {
                $list[$k] = json_decode($li, true);
            }
        }

        return $list;
    }

    public function field($field = [])
    {
        if (empty($field)) {
            return $this;
        } elseif (is_string($field)) {
            $field = array_map('trim', explode(',', $field));
            $this->columns = $field;
        } elseif (is_array($field)) {
            $this->columns = $field;
        } else {
            $this->columns = func_get_args();
        }

        return $this;
    }
}
